/*
	eXordiumCore
	Just connect the modules.
*/
module eXordiumCore
(
	input	wire	[00:0]	clk,
	input	wire	[00:0]	rst,
	
	input	wire	[31:0]	instr,
	output	wire	[31:0]	instrAddr,		// pc[31:02] link to InstROM's [29:00]
	
	//-------------------BUS----------------------
    output 	wire 	[31:0]	WB_ADRo,
    output 	wire 	[31:0]	WB_DATo,
    input 	wire 	[31:0]	WB_DATi,
    output 	wire 			WB_WEo,
    output 	wire 			WB_CYCo,
    input 	wire 			WB_ACKi
);

	
//------------------------------------Signal wire--------------------------------
	// pcReg
	wire 			[31:0]	pc;
	assign 					instrAddr = pc;
	// RegFile
	wire			[31:0]	gprWriteBackData;
	// Decoder
	wire			[02:0]	func;
	wire			[31:0]	imm;
	wire			[04:0]	gprId1;
	wire			[04:0]	gprId2;
	wire					operandSel1;
	wire					operandSel2;
	wire			[04:0]	shamt;
	wire					aluFuncSel;
	wire			[04:0]	gprWriteBackId;
	wire					gprWriteBackEn;
	wire					gprWriteBackFromALU;
	wire					gprWriteBackFromSpecialAdder;
	wire					gprWriteBackFromPcPlus4;
	wire					gprWriteBackFromLSU;
	wire					jumpFlag;
    wire            [31:0]  branchOffset;
	wire			[02:0]	loadDataAdjust;  
    wire                    aluriOp;
    wire                    branchOp;
	wire					loadOp;
	wire					storeOp;
	// Operand Mux
	wire			[31:0]	gprOutput1;
	wire			[31:0]	gprOutput2;
	wire			[31:0]	operand1;	
	wire			[31:0]	operand2;
	// ALU
	wire			[31:0]	aluRes;
	wire			[31:0]	specialAdderRes;
	wire			[31:0]	pcPlus4Res;
    // bpu
	wire	                branchFlag;
	// LSU
	wire			[31:0]	lsuDataOut;
	wire					lsuDone;
//--------------------------------------Signal wire End--------------------------------	
	
// --------------------------------------Instances--------------------------------------
	
	// -----------------------pcReg---------------------------
	
	pcReg			                    pcReg
	(
		.clk							(clk),
		.rst							(rst),
		.jumpFlag						(jumpFlag),
		.branchFlag						(branchFlag),
		.jumpAddr						(specialAdderRes),
        .branchOffset                   (branchOffset),
		.loadOp						    (loadOp),
		.storeOp						(storeOp),
		.lsuDone						(lsuDone),
		.pc								(pc)
	);
	
	
	// -----------------------Decoder-----------------------------
	decoder		                        decoder
	(
		.instr							(instr),
		.func							(func),
		.imm							(imm),
		.gprId1						    (gprId1),
		.gprId2						    (gprId2),
		.operandSel1					(operandSel1),
		.operandSel2					(operandSel2),
		.shamt							(shamt),
		.aluFuncSel						(aluFuncSel),
		.gprWriteBackId					(gprWriteBackId),
		.gprWriteBackEn					(gprWriteBackEn),
		.gprWriteBackFromALU			(gprWriteBackFromALU),
		.gprWriteBackFromSpecialAdder	(gprWriteBackFromSpecialAdder),
		.gprWriteBackFromPcPlus4		(gprWriteBackFromPcPlus4),
		.gprWriteBackFromLSU			(gprWriteBackFromLSU),
		.jumpFlag						(jumpFlag),
        .branchOffset                   (branchOffset),
        .aluriOp                        (aluriOp),
        .branchOp						(branchOp),
		.loadOp							(loadOp),
		.storeOp						(storeOp)
	);
	
	
	// -----------------------registerFile-----------------------------
	registerFile	                    registerFile
	(
		.clk							(clk),
		.gprWriteBackEn					(gprWriteBackEn),
		.gprWriteBackData				(gprWriteBackData),
		.gprWriteBackId					(gprWriteBackId),
		.gprId1							(gprId1),
		.gprId2							(gprId2),
		.gprOutput1						(gprOutput1),
		.gprOutput2						(gprOutput2)
	);
	
	
	
	// ---------------------Operands Mux----------------------------
	operandsMux	                        operandsMux
	(
		.gprOutput1						(gprOutput1),
		.pc								(pc),
		.operandSel1					(operandSel1),
		.gprOutput2						(gprOutput2),
		.imm							(imm),
		.operandSel2					(operandSel2),
		.operand1						(operand1),
		.operand2						(operand2)
	);
	// -------------------------------------ALU--------------------------
	alu				                    alu
	(
		.operand1						(operand1),
		.operand2						(operand2),
        .pc                             (pc),
		.shamt							(shamt),
		.func							(func),
		.aluFuncSel						(aluFuncSel),
        .aluriOp                        (aluriOp),

		.aluRes							(aluRes),
		.specialAdderRes				(specialAdderRes),
		.pcPlus4Res						(pcPlus4Res)
	);
	// ---------------------------------bpu-----------------------------------
	bpu				                    bpu
	(
		.operand1						(operand1),
		.operand2						(operand2),
		.branchOp						(branchOp),
		.func							(func),
		.branchFlag						(branchFlag)
	);
	//-----------------------------------lsu----------------------------------
	lsu				                    lsu
	(
	//CPU
		.addr							(specialAdderRes),
		.lsuDataIn						(gprOutput2),
		.loadOp						    (loadOp),
		.storeOp						(storeOp),
		.lsuDone						(lsuDone),
		.lsuDataOut						(lsuDataOut),
		.func                           (func),

	//Bus
		.WB_ADRo				        (WB_ADRo),
		.WB_DATo				        (WB_DATo),
		.WB_DATi 					    (WB_DATi),
		.WB_WEo  				       	(WB_WEo),
		.WB_CYCo        				(WB_CYCo),
		.WB_ACKi        				(WB_ACKi)	
	);
	// -----------------------gprWriteBackDataMux---------------------------
	gprWriteBackDataMux	                gprWriteBackDataMux
	(
		.gprWriteBackFromALU			(gprWriteBackFromALU),
		.gprWriteBackFromSpecialAdder	(gprWriteBackFromSpecialAdder),
		.gprWriteBackFromPcPlus4		(gprWriteBackFromPcPlus4),
		.gprWriteBackFromLSU			(gprWriteBackFromLSU),
		.aluRes							(aluRes),
		.specialAdderRes				(specialAdderRes),
		.pcPlus4Res						(pcPlus4Res),
		.lsuDataOut						(lsuDataOut),
		.gprWriteBackData				(gprWriteBackData)
	);
// ----------------------------------Instances End------------------------------------	
	
endmodule